Skip to main content

Overview

This module provides cryptographically secure random number generation (CSPRNG) using platform-specific secure random sources. All randomness is suitable for cryptographic key generation and security-critical operations.

Core functions

csprng_bytes

Generates cryptographically secure random bytes.
uint8_t*
Output buffer to fill with random bytes
size_t
Number of random bytes to generate
Example:
This function calls std::abort() if the system random source fails. This is intentional to prevent insecure fallback behavior.

csprng_u64

Generates a cryptographically secure random 64-bit unsigned integer.
uint64_t
Random 64-bit value
Example:

Utility functions

load_le64

Loads a 64-bit integer from a byte array in little-endian format.
const uint8_t*
Pointer to 8 bytes
uint64_t
64-bit integer in host byte order
Example:

store_le64

Stores a 64-bit integer into a byte array in little-endian format.
uint8_t*
Output buffer (must have space for 8 bytes)
uint64_t
Value to store
Example:

Platform-specific implementations

macOS / BSD

Uses arc4random_buf() for cryptographically secure random bytes.
Available on macOS, FreeBSD, OpenBSD, and NetBSD.

Linux

Uses the getrandom() system call with fallback to /dev/urandom.
  • Primary: getrandom() system call (Linux 3.17+)
  • Fallback: Reads from /dev/urandom if getrandom() fails
  • Handles interruptions (EINTR) automatically

Windows

Uses BCryptGenRandom() with the system-preferred RNG.
Requires bcrypt.lib (automatically linked via pragma).

Fallback (portable)

Uses std::random_device for platforms without native secure random support.
The fallback implementation may not be cryptographically secure on all platforms. Prefer platforms with native secure random support for production use.

Security properties

Cryptographic strength

All platform-specific implementations provide:
  • Unpredictability: Output cannot be predicted from previous values
  • Uniform distribution: All bit patterns equally likely
  • Sufficient entropy: Backed by hardware or OS entropy sources
  • Forward secrecy: Compromise of current state doesn’t reveal past outputs

Error handling

If random generation fails, the library calls std::abort() rather than returning an error. This is a deliberate security decision:
  • Prevents accidental use of non-random or predictable values
  • Makes failures immediately visible during testing
  • Avoids complex error propagation through cryptographic code

Usage patterns

Key generation

Nonce generation

Random seed buffer

Random field element

Testing considerations

For deterministic testing:
  • The CSPRNG is not seedable by design (security requirement)
  • For reproducible tests, use a separate PRNG (like SHAKE256)
  • Never use test-only random sources in production code
Example deterministic testing pattern:

Relationship to other modules

The random module is used by:
  • Types (types.hpp): make_nonce128(), rand_fp_nonzero()
  • Hash (hash.hpp): Seeding XOFs and PRNGs
  • Key generation: Generating secret keys and randomness
  • Encryption: Sampling error vectors and random masks

Performance characteristics

  • csprng_u64(): ~10-50 CPU cycles on modern hardware
  • csprng_bytes(): ~1-5 GB/s throughput for bulk generation
  • Dominated by system call overhead for small requests
  • Consider batching requests for small values
Batching example:
  • Types - Uses random generation for nonces and field elements
  • Hash - Deterministic randomness expansion via XOF
  • Field operations - Random field element generation